DEFINITION MODULE exeCut; (* Leo 30-Mar-90. (c) KRONOS *)

IMPORT  BIO;

VAL done: BOOLEAN;
    note: ARRAY [0..127] OF CHAR;
   error: INTEGER;

    task: INTEGER;
   cause: BITSET;

CONST (* cause *)
   awake = {0};   break = {1};   abort = {2};   cfi = {3};

PROCEDURE system(command: ARRAY OF CHAR);

------------------- FOR HACKERS APPLICATIONS -------------------
                   --------------------------
VAL etc: BIO.PATHs;
   mask: BITSET;

PROCEDURE hold_break(on: BOOLEAN);
PROCEDURE break_mask(mask: BITSET);

END exeCut.

(**************************************************************

                      БИБЛИОТЕКА exeCut

   task - номер последней запущенной задачи
   done, note, error :
     если при исполнении system(...) возникла ошибка
     до запуска задачи, то:
       done=FALSE,
       error=код возникшей ошибки,
       note=либо пусто, либо уточнение

     после нормального запуска задачи всегда done=TRUE

     результат завершения задачи: break, awake, abort.

     если awake=TRUE то на error и остальное можно
     не обращать внимания;

     break=TRUE обозначает прерывание задачи клавиатурой.

     abort=TRUE обозначает аварийное завершение задачи.
       при этом завершение методом HALT(number) или ASSERT(FALSE,number)
       приводит к тому, что number в переменной error

     NOTE: может быть note#"" при error=ok, done=TRUE
     и прочих переменных в нормальном состоянии !!!

   Переменные состояния (ENVIRONMENT)  [default value]

   SHELL   имя утилиты которая вызывается при
           обнаружении нетекстового исполняемого файла
           ["shell"].
           Копируется обычным образом;
           ее отсутствие приводит к невозможности исполнить
           командный файл.

   STK     размер стека для запускаемых задач
           ["4KB"].
           Копируется обычным образом.
           Если в окружении отсутсвует, то размер считается 4KB.

   ALIAS   строка переименования модулей
           [""]
             синтаксис:
             "=" module file {"=" module file }

   BIN     строка имен директорий на которых
           производится поиск кодофайлов

   ETC     строка имен директорий на которых
           производится поиск командных файлов
           и файлов данных

   CD      имя текущей директории.
           ее корректность поддерживается библиотекой.
           команда "CD=dir" эквивалентна
           перестановке текущей директории на "dir",
           с соответствующей МОДИФИКАЦИЕЙ ИМЕНИ,
           то есть:
             если
               CD=/usr/owner
             и поступает команда
               CD=..  ,
             то текущая директория меняется на "/usr",
             и после ее исполнения
               CD=/usr

   TTY     имя устройства-экрана
   KEY     имя устройства-клавиатуры

   HOME    имя home директории пользователя

   TASK    номер задачи которая работает с exeCut.
           Считается локальной и не копируется.
           При инициализации exeCut, создается.

   BASE    номер задачи "на базе" которой запускаются
           и инсталируются другие задачи
           Если отсутствует, то создается при
           инициализации со значением ["$TASK"].
           Ее отсутствие приводит к ошибке при
           запуске задач.

   FATHER  номер задачи родителя.
           Если отсутствует, то создается при инициализации.
           При запуске задачи создается с правильным значением.

   NAME    имя задачи с которой ведется работа

   USER    имя пользователя

   Синтаксис команд:

   command ::= change_environment
             | task_control
             | run_task .
          (*
             | mount_unmount
          *)

   change_environment ::=
               var_name "=" string.

   task_control ::=
                "stop"     task_number { task_number }
             |  "kill"     task_number { task_number }
             |  "wait"     task_number { task_number } .

   run_task ::=
         [ "{" {change_environment} {alias} "}" ]
         task_name { args } [ "&" ].

   alias = interface|unload|rename .
   interface = "+" module_name .
   unload    = "-" module_name .
   rename    = "=" module_name file_name .

   mount_unmount ::=
               "mount"   ["-ro"] directory device
             | "unmount" ["-ro"] directory device.

------------------------------------------------------------

   При запуске задач используются:
     env."ALIAS" вместе с соотв. частью прелюдии
     env."BASE"; если отсутствует, то ошибка.
     env."STK";  если отсутствует, то 4КБ.

   В случае обнаружения библиотекой exeCut командного файла
                          например

   { BASE=$FATHER ALIAS=GRAPHIC:IGD480
     +myDataBase -newSpateSheet }
        profile with three arguments &

   она извлекает из ОКРУЖЕНИЯ строчку SHELL (пусть, например
   SHELL=DBsubmit) и производит запуск

   { BASE=$FATHER ALIAS=GRAPHIC:IGD480
     +myDataBase -newSpateSheet }
     DBsubmit <profile with three arguments &

   после чего в переменную task помещает номер запущенной
   задачи DBsubmit; При отсутствии строчки "SHELL", - ошибка.

     Если   задача  запущена  без  открепления  exeCut  будет
ожидать ее окончания или прерывания/открепления с клавиатуры.

     После  завершения  задачи методом HALT(0) в ее окружении
библиотека  ищет  строку с именем "CHAIN" и если она есть, то
после  завершения  процедура  system  исполняется  еще  раз с
аргументом - этой строкой.

     Три  переменные  abort,  break,  awake  позволят  узнать
причину успешного окончания процедуры system.

     Любая    задача    запушенная   библиотекой   exeCut   и
остановленная в результате аварии или прерывания с клавиатуры
не уничтожается и продолжает лежать холодным трупом вплоть до
явного уничтожения командой kill.

     В  любом  месте  строки  перед  исполнением  команды все
последовательности $name заменяются по возможности на строчки
из окружения.

------------------------------------------------------------

     Как  исполнить  задачу  (командный  файл)  имя  которого
совпадает с названием команды в exeCut?

     - Предварить имя такой задачи значком "\"
     - Указать расширитель .cod для кодофайлов
     - Указать расширитель .@   для командных файлов

     Как передать в качестве последнего аргумента "&"?

     - Предварить "&" значком "\"

     Как передать в качестве последнего аргумента "\&"?

     - "\\&"

     Как передать в качестве последнего аргумента "\\&"?

     - "\\\&"

     .....

     Как запретить раскрытие имени из ОКРУЖЕНИЯ?

     - Предварить знак "$" перед именем значком "\"
